package com.ruoyi.service.service.impl;

import com.ruoyi.service.domain.*;
import com.ruoyi.service.entity.order.*;
import com.ruoyi.service.entity.order.pay.PCOrderPayRet;
import com.ruoyi.service.entity.order.process.PCOrderProcess;
import com.ruoyi.service.entity.order.process.PCOrderProcessRet;
import com.ruoyi.service.entity.order.process.PCProcessItems;
import com.ruoyi.service.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.ruoyi.common.utils.SecurityUtils.getUsername;

@Component
public class PcOrderService {


    @Autowired
    private ServiceOrdersMapper ordersMapper;

    @Autowired
    private ServiceNurseMapper nurseMapper;

    @Autowired
    private ServiceMycartMapper mycartMapper;

    @Autowired
    private ServiceItemscomboMapper itemscomboMapper;

    @Autowired
    private ServiceComboMapper comboMapper;

    @Autowired
    private ServiceItemsMapper itemsMapper;

    @Autowired
    private ServiceAddressMapper addressMapper;

    @Autowired
    private ServicePayroadMapper payroadMapper;

    @Autowired
    private ServiceOrderscomboMapper orderscomboMapper;

    @Autowired
    private ServiceOrdersitemsMapper ordersitemsMapper;

    @Autowired
    private ServicePackagescomboMapper packagescomboMapper;

    @Autowired
    private ServicePackagesMapper packagesMapper;

    @Autowired
    private ServiceOrderspackagesMapper orderspackagesMapper;

    @Autowired
    private ServicePayMapper payMapper;

    @Autowired
    private ServiceAssessmentMapper assessmentMapper;

    @Autowired
    private ServicePictureMapper pictureMapper;

    @Autowired
    private ServiceCodeMapper codeMapper;

    @Autowired
    private ServiceRefuseMapper refuseMapper;

    @Autowired
    private ServiceOrdernurseMapper ordernurseMapper;

    @Autowired
    private ServiceServedMapper servedMapper;

    @Autowired
    private ServiceUsersMapper usersMapper;

    @Autowired
    private ServiceReasonrefuseMapper reasonrefuseMapper;

    @Autowired
    private ServiceOrderotherpayMapper orderotherpayMapper;

    @Autowired
    private ServiceTimeMapper timeMapper;

    @Autowired
    private ServiceReasonstopMapper reasonstopMapper;

    @Autowired
    private ServiceActionMapper actionMapper;



    @Transactional //需要
    public Page<PCOrderListRet> getOrderList(String labelStatus, Integer page, Integer size)
    {
        List<PCOrderListRet> retOrderList = new ArrayList<PCOrderListRet>();
        try {

            ServiceOrders searchOrder = new ServiceOrders();

            Long[] orderServiceFlags = null;

            if (labelStatus.equals("unNormal")){
                searchOrder.setOrderStatus(9);
            }

            if (labelStatus.equals("new")){
                orderServiceFlags = new Long[]{5L,6L,7L};
            } else if (labelStatus.equals("unserved")) {
                orderServiceFlags = new Long[]{8L};
            } else if (labelStatus.equals("serving")) {
                orderServiceFlags = new Long[]{9L,10L,11L};
            } else if (labelStatus.equals("unsettled")) {
                orderServiceFlags = new Long[]{12L,13L};
            }else if (labelStatus.equals("canceled")){
                orderServiceFlags = new Long[]{2L,4L};
            }else {
                orderServiceFlags = new Long[]{1L,2L,3L,4L,5L,6L,7L,8L,9L,10L,11L,12L,13L,14L,15L,16L,17L};
            }

            List<ServiceOrders> ordersList = new ArrayList<ServiceOrders>();
            for (Long flag : orderServiceFlags) {
                searchOrder.setOrderServiceflag(Math.toIntExact(flag));

                List<ServiceOrders> ordersAll = ordersMapper.selectServiceOrdersList(searchOrder);
                for (ServiceOrders order : ordersAll){
                    ordersList.add(order);
                }
            }

            for (ServiceOrders order : ordersList) {

                PCOrderListRet retOrderVONode = new PCOrderListRet();
                Long prePaid = 0L;

                //订单信息
                retOrderVONode.init(order);

                List<ServiceOrderscombo> orderscomboList = orderscomboMapper.selectServiceOrderscomboByOrderId(order.getOrderId());
                for (ServiceOrderscombo orderscombo : orderscomboList) {
                    PCOrderInfo retVONode = new PCOrderInfo();
                    ServiceItemscombo itemscombo = itemscomboMapper.selectByComboId(orderscombo.getOrderscomboComboid());
                    ServiceItems item = itemsMapper.selectServiceItemsByItemId(itemscombo.getItemscomboItemid());
                    ServiceCombo combo = comboMapper.selectServiceComboByComboIdNew(orderscombo.getOrderscomboComboid());
                    retVONode.initItem(item);//项目信息录入
                    Long price = 0L;
                    retVONode.setSpecId(combo.getComboId());
                    retVONode.setSpecName(combo.getComboName());
                    retVONode.setSpecPrice(combo.getComboCurrentprice());
                    retVONode.setCount(orderscomboList.get(0).getOrderscomboCount());
                    price += combo.getComboPrice();

                    List<ServicePackagescombo> packagescombos = packagescomboMapper.selectServicePackagescomboByComboId(combo.getComboId());
                    for (ServicePackagescombo packagescombo : packagescombos) {
                        ServicePackages packages = packagesMapper.selectServicePackagesByPackagesId(packagescombo.getPackagescomboPackagesid());
                        ServiceOrderspackages searchOrdersPackages = new ServiceOrderspackages();
                        searchOrdersPackages.setOrderspackagesOrderid(order.getOrderId());
                        searchOrdersPackages.setOrderspackagesPackageid(packages.getPackagesId());
                        searchOrdersPackages.setOrderspackagesDelFlag("0");
                        List<ServiceOrderspackages> orderspackagesList = orderspackagesMapper.selectServiceOrderspackagesList(searchOrdersPackages);
                        if (orderspackagesList.size() > 0) {
                            retVONode.setPkgId(packages.getPackagesId());
                            retVONode.setPkgName(packages.getPackagesName());
                            retVONode.setPkgAmount(packages.getPackagesPrice());
                            price += packages.getPackagesPrice();
                            break;
                        }


                    }

                    retVONode.setPrice(price);
                    retVONode.setCost(price * retVONode.getCount());
                    prePaid += retVONode.getCost();
                    retVONode.setFromNur(false);
                    ServiceUsers users = usersMapper.selectServiceUsersByUsersId(order.getOrderUserid());
                    if (!orderscombo.getOrderscomboCreateBy().equals(users.getUsersName())) {
                        retVONode.setFromNur(true);
                    }

                    if (retOrderVONode.getOrderInfo() == null) {
                        retOrderVONode.setOrderInfo(new ArrayList<PCOrderInfo>());
                    }
                    retOrderVONode.getOrderInfo().add(retVONode);

                    int buttonFlag = 0;
                    int addBTFlag = 0;
                    ServiceOrders orders = ordersMapper.selectServiceOrdersByOrderId(order.getOrderId());
                    List<ServiceOrderspackages> orderspackagesList = orderspackagesMapper.selectOrderspackagesByOrderId(order.getOrderId());

                    if (retOrderVONode.getButtons() == null) {
                        retOrderVONode.setButtons(new ArrayList<PCOrderButton>());
                    }

                    for (PCOrderButton button : retOrderVONode.getButtons()) {
                        if (button.getType().equals("orderDetial")) {
                            addBTFlag = 1;
                            break;
                        }
                    }
                    if (addBTFlag == 0) {
                        retOrderVONode.getButtons().add(new PCOrderButton("orderDetial", "订单详情"));
                        addBTFlag = 0;
                    }
                    for (PCOrderButton button : retOrderVONode.getButtons()) {
                        if (button.getType().equals("orderProcess")) {
                            addBTFlag = 1;
                            break;
                        }
                    }
                    if (addBTFlag == 0) {
                        retOrderVONode.getButtons().add(new PCOrderButton("orderProcess", "订单跟踪"));
                        addBTFlag = 0;
                    }

                    List<ServicePicture> medicals = pictureMapper.selectMedicalListByOrderId(order.getOrderId());


                    List<ServiceOrdernurse> ordernurseList = ordernurseMapper.selectServiceOrdernurseListByOrderId(order.getOrderId());
                    List<PCNurseInfo> nurseInfoList = new ArrayList<PCNurseInfo>();
                    for (ServiceOrdernurse ordernurse : ordernurseList) {
                        ServiceNurse nurse = nurseMapper.selectServiceNurseByNurseId(ordernurse.getOrdernurseNurseid());
                        if (nurse != null) {
                            PCNurseInfo nurseInfo = new PCNurseInfo();

                            nurseInfo.setId(nurse.getNurseId());
                            nurseInfo.setName(nurse.getNurseName());
                            nurseInfo.setTel(nurse.getNurseTelephonenumber());

                            nurseInfoList.add(nurseInfo);
                        }
                    }
                    retOrderVONode.setNurseInfo(nurseInfoList);

                    //被服务信息
                    retOrderVONode.setServeInfo(getServeInfo(order.getOrderId()));
                    //支付信息
                    if (orders.getOrderPay() != null){
                        retOrderVONode.setPrePaid(getPrePaid(order.getOrderId()));
                        retOrderVONode.setActual(getActual(order.getOrderId()));
                        retOrderVONode.setDifference(getDifference(retOrderVONode.getActual(), retOrderVONode.getPrePaid()));
                        retOrderVONode.setTotalAmount(retOrderVONode.getPrePaid().getTotalAmount());
                        if (retOrderVONode.getActual() != null){
                            retOrderVONode.setTotalAmount(retOrderVONode.getActual().getTotalAmount());
                        }
                    }
                }
                retOrderList.add(retOrderVONode);
            }


            // 分页逻辑
            Pageable pageable = PageRequest.of(page, size);
            int start = (int) pageable.getOffset();
            int end = Math.min((start + pageable.getPageSize()), retOrderList.size());
            List<PCOrderListRet> pagedItemsList = retOrderList.subList(start, end);

            return new PageImpl<>(pagedItemsList, pageable, retOrderList.size());

        }catch (Exception e){
            return null;
        }
    }


    @Transactional
    public PCOrderDetailRet getOrderDetail(Long orderId)
    {
        PCOrderDetailRet retOrderVONode = new PCOrderDetailRet();
        try {
            ServiceOrders searchOrder = new ServiceOrders();
            searchOrder.setOrderId(orderId);

            ServiceOrders order = ordersMapper.selectServiceOrdersByOrderId(orderId);
            if (order == null){
                throw new Exception("未找到订单信息");
            }

            //订单信息
            retOrderVONode.init(order);

            //验证码
            ServiceCode code = codeMapper.selectServiceCodeByOrderId(order.getOrderId());
            ServicePay pay = payMapper.selectServicePayByPayId(order.getOrderPay());
            if (code != null){
                retOrderVONode.setOrderPayId(pay.getPayAdvancepaycode());
                DateFormat cstFormate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String payTime = cstFormate.format(pay.getPayCreateTime());
                retOrderVONode.setOrderPayTime(payTime);
                if (pay.getPayFinalpay() != null){
                    String settleTime = cstFormate.format(pay.getPayUpdateTime());
                    retOrderVONode.setOrderSettleTime(settleTime);
                }
            }

            ServiceUsers userInfo = usersMapper.selectServiceUsersByUsersId(order.getOrderUserid());
            retOrderVONode.initUserInfo(userInfo);

            //护士信息
            List<ServiceOrdernurse> ordernurseList = ordernurseMapper.selectServiceOrdernurseListByOrderId(order.getOrderId());
            List<PCNurseInfo> nurseInfoList = new ArrayList<PCNurseInfo>();
            for (ServiceOrdernurse ordernurse : ordernurseList) {
                ServiceNurse nurse = nurseMapper.selectServiceNurseByNurseId(ordernurse.getOrdernurseNurseid());
                if (nurse != null) {
                    PCNurseInfo nurseInfo = new PCNurseInfo();

                    nurseInfo.setId(nurse.getNurseId());
                    nurseInfo.setName(nurse.getNurseName());
                    nurseInfo.setTel(nurse.getNurseTelephonenumber());

                    nurseInfoList.add(nurseInfo);
                }
            }
            retOrderVONode.setNurseInfo(nurseInfoList);

            //被服务信息
            retOrderVONode.setServeInfo(getServeInfo(order.getOrderId()));


            List<ServiceOrderscombo> orderscomboList = orderscomboMapper.selectServiceOrderscomboByOrderId(order.getOrderId());
            for (ServiceOrderscombo orderscombo : orderscomboList) {
                PCOrderInfo retVONode = new PCOrderInfo();
                //PCOrderDetailInfo retVONode = new PCOrderDetailInfo();

                ServiceOrders orders = ordersMapper.selectServiceOrdersByOrderId(orderId);
                List<ServiceOrderspackages> orderspackagesList = orderspackagesMapper.selectOrderspackagesByOrderId(order.getOrderId());
                if (retOrderVONode.getButtons() == null){
                    retOrderVONode.setButtons(new ArrayList<PCOrderButton>());
                }
                int addBTFlag = 0;
                if (order.getOrderServiceflag() == 14){
                    for (PCOrderButton button : retOrderVONode.getButtons()) {
                        if(button.getType().equals("stop")){
                            addBTFlag = 1;
                            break;
                        }
                    }
                    if(addBTFlag == 0){
                        retOrderVONode.getButtons().add(new PCOrderButton("stop", "关闭处理"));
                        addBTFlag = 0;
                    }
                }

                List<ServicePicture> medicals = pictureMapper.selectMedicalListByOrderId(order.getOrderId());
                PCProofsInfo proofsInfo = new PCProofsInfo();
                proofsInfo.setMedicalImages(new ArrayList<String>());
                proofsInfo.setConsumeImages(new ArrayList<String>());
                for (ServicePicture medical : medicals){
                    proofsInfo.getMedicalImages().add(medical.getPicturePic());
                }
                List<ServicePicture> consumes = pictureMapper.selectConsumeListByOrderId(order.getOrderId());
                for (ServicePicture consume : consumes){
                    proofsInfo.getConsumeImages().add(consume.getPicturePic());
                }
                if (medicals.size() == 0) proofsInfo.setMedicalTips("请同通知用户上传处方、病历等就医证明");
                if (consumes.size() == 0) proofsInfo.setConsumeTips("请通知用户上传耗材证明");
                retOrderVONode.setProofsInfo(proofsInfo);
                for(ServiceOrderspackages orderspackages : orderspackagesList){
                    if (orderspackages.getOrderspackagesPackageid() == 0){
                        proofsInfo.setNeedUploadConsume(true);
                        break;
                    }
                }


            }

            retOrderVONode.initOrderInfo(getPaidInfo(order.getOrderId()));
            retOrderVONode.setCheckInfo(getCheckInfo(order.getOrderId()));

            return retOrderVONode;

        }catch (Exception e){
            return null;
        }
    }




    @Transactional
    public PCServeInfo getServeInfo(Long orderId) {
        try {
            ServiceOrders orders = ordersMapper.selectServiceOrdersByOrderId(orderId);

            ServiceServed served = servedMapper.selectServiceServedByServedId(orders.getOrderServedid());
            ServiceAddress address = addressMapper.selectServiceAddressByAddressId(orders.getOrderAddressid());
            PCServeInfo serveInfo = new PCServeInfo();
            serveInfo.setServePerson(served.getServedName());
            serveInfo.setServeTel(served.getServedTelephonenumber());
            serveInfo.setServeAddress(address.getAddressInfo());

            ServiceUsers users = usersMapper.selectServiceUsersByUsersId(served.getServedUserid());
            serveInfo.setUsername(users.getUsersName());
            DateFormat cstFormate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String serveTime = cstFormate.format(orders.getOrderScheduledtime());
            serveInfo.setServeTime(serveTime);

            return serveInfo;
        }catch (Exception e){
            return null;
        }
    }


    @Transactional
    public PCActual getActual(Long orderId) {
        try {
            PCActual actual = new PCActual();
            PCServiceItems serviceItems = getServiceItems(orderId);
            PCPackageItems packageItems = getPackageItems(orderId);
            PCTaxiItems taxiItems = getTaxiItems(orderId);
            PCOtherItems otherItems = getOtherItems(orderId);
            actual.setServiceItems(serviceItems);
            actual.setPackageItems(packageItems);
            actual.setTaxiItems(taxiItems);
            actual.setOtherItems(otherItems);

            actual.setTotalAmount(serviceItems.getAmount() + packageItems.getAmount() + taxiItems.getAmount() + otherItems.getAmount());

            return actual;
        }catch (Exception e){
            return null;
        }
    }

    @Transactional
    public PCServiceItems getServiceItems(Long orderId) {
        try {

            PCServiceItems serviceItems = new PCServiceItems();
            if (serviceItems.getItems() == null){
                serviceItems.setItems(new ArrayList<PCServiceItemsItem>());
            }
            Long amount = 0L;
            Long pre = 0L;
            ServiceOrders order = ordersMapper.selectServiceOrdersByOrderId(orderId);
            List<ServiceOrderscombo> orderscomboList = orderscomboMapper.selectServiceOrderscomboByOrderId(orderId);
            for (ServiceOrderscombo orderscombo : orderscomboList){
                PCServiceItemsItem itemNode = new PCServiceItemsItem();
                ServiceCombo combo = comboMapper.selectServiceComboByComboId(orderscombo.getOrderscomboComboid());
                itemNode.setName(combo.getComboName());
                itemNode.setPrice(combo.getComboCurrentprice());
                itemNode.setCount(orderscombo.getOrderscomboCount());
                itemNode.setAmount(combo.getComboCurrentprice() * orderscombo.getOrderscomboCount());

                itemNode.setId(combo.getComboId());
                itemNode.setPre(itemNode.getAmount());
                itemNode.setBill(itemNode.getAmount());

                if (!orderscombo.getOrderscomboCreateBy().equals(order.getOrderCreateBy())){
                    itemNode.setFromNur(true);
                    pre -= itemNode.getAmount();
                    itemNode.setPre(null);
                }
                amount = amount + itemNode.getAmount();
                serviceItems.getItems().add(itemNode);
            }
            serviceItems.setAmount(amount);
            serviceItems.setPre(amount + pre);
            serviceItems.setBill(amount);
            return serviceItems;
        }catch (Exception e){
            return null;
        }
    }

    @Transactional
    public PCPackageItems getPackageItems(Long orderId) {
        try {

            PCPackageItems packageItems = new PCPackageItems();
            if (packageItems.getItems() == null){
                packageItems.setItems(new ArrayList<PCPackageItemsItem>());
            }
            Long amount = 0L;
            Long pre = 0L;
            ServiceOrders order = ordersMapper.selectServiceOrdersByOrderId(orderId);
            List<ServiceOrderspackages> orderspackagesList = orderspackagesMapper.selectOrderspackagesByOrderId(orderId);
            for (ServiceOrderspackages orderspackages : orderspackagesList){
                PCPackageItemsItem itemNode = new PCPackageItemsItem();
                ServicePackages packages = packagesMapper.selectServicePackagesByPackagesId(orderspackages.getOrderspackagesPackageid());
                itemNode.setName(packages.getPackagesName());
                itemNode.setPrice(packages.getPackagesPrice());
                itemNode.setCount(orderspackages.getOrderspackagesCount());
                itemNode.setAmount(packages.getPackagesPrice() * orderspackages.getOrderspackagesCount());

                itemNode.setId(packages.getPackagesId());
                itemNode.setPre(itemNode.getAmount());
                itemNode.setBill(itemNode.getAmount());

                if (!orderspackages.getOrderspackagesCreateBy().equals(order.getOrderCreateBy())){
                    itemNode.setFromNur(true);
                    pre -= itemNode.getAmount();
                    itemNode.setPre(null);
                }
                amount = amount + itemNode.getAmount();
                packageItems.getItems().add(itemNode);
            }
            packageItems.setAmount(amount);
            packageItems.setPre(amount + pre);
            packageItems.setBill(amount);
            return packageItems;
        }catch (Exception e){
            return null;
        }
    }

    @Transactional
    public PCTaxiItems getTaxiItems(Long orderId) {
        try {

            PCTaxiItems taxiItems = new PCTaxiItems();
            if (taxiItems.getItems() == null){
                taxiItems.setItems(new ArrayList<PCTaxiItemsItem>());
            }
            Long amount = 0L;
            ServicePayroad payroad = payroadMapper.selectServicePayroadByOrderId(orderId);
            PCTaxiItemsItem itemNode = new PCTaxiItemsItem();
            if (payroad.getPayroadBill() != null && payroad.getPayroadActualpay() != null){
                itemNode.setType("goto");
                itemNode.setAmount(payroad.getPayroadBill());
                amount = amount + payroad.getPayroadBill();
                taxiItems.getItems().add(itemNode);

                itemNode = new PCTaxiItemsItem();
                itemNode.setType("back");
                itemNode.setAmount(payroad.getPayroadActualpay());
                amount = amount + payroad.getPayroadActualpay();
                taxiItems.getItems().add(itemNode);
            }

            taxiItems.setAmount(amount);
            taxiItems.setPre(payroad.getPayroadAdvancepay());
            taxiItems.setBill(amount);
            return taxiItems;
        }catch (Exception e){
            return null;
        }
    }


    @Transactional
    public PCOtherItems getOtherItems(Long orderId) {
        try {

            PCOtherItems otherItems = new PCOtherItems();
            if (otherItems.getItems() == null){
                otherItems.setItems(new ArrayList<PCOtherItemsItem>());
            }
            Long amount = 0L;
            List<ServiceOrderotherpay> orderotherpayList = orderotherpayMapper.selectOtherpayByOrderId(orderId);
            for (ServiceOrderotherpay orderotherpay : orderotherpayList){
                PCOtherItemsItem itemNode = new PCOtherItemsItem();
                itemNode.setName(orderotherpay.getOrderotherpayDesc());
                itemNode.setPrice(orderotherpay.getOrderotherpayPrice());
                itemNode.setCount(orderotherpay.getOrderotherpayCount());
                itemNode.setAmount(orderotherpay.getOrderotherpayPrice() * orderotherpay.getOrderotherpayCount());
                amount = amount + itemNode.getAmount();
                otherItems.getItems().add(itemNode);
            }
            otherItems.setAmount(amount);

            return otherItems;
        }catch (Exception e){
            return null;
        }
    }

    @Transactional
    public PCPrepaid getPrePaid(Long orderId) {
        try {

            PCPrepaid prepaid = new PCPrepaid();

            ServiceOrders orders = ordersMapper.selectServiceOrdersByOrderId(orderId);
            ServicePay pay = payMapper.selectServicePayByPayId(orders.getOrderPay());
            ServicePayroad payroad = payroadMapper.selectServicePayroadByOrderId(orderId);

            prepaid.setTotalAmount(pay.getPayAdvancepay() + payroad.getPayroadAdvancepay());
            prepaid.setSpecAmount(pay.getPayBill());
            prepaid.setPkgAmount(pay.getPayAdvancepay() - pay.getPayBill());
            prepaid.setTaxiAmount(payroad.getPayroadAdvancepay());

            return prepaid;

        }catch (Exception e){
            return null;
        }
    }


    @Transactional
    public PCDifference getDifference(PCActual actual, PCPrepaid prepaid) {
        try {

            PCDifference difference = new PCDifference();
            Long amount = 0L;
            if (difference.getItems() == null){
                difference.setItems(new ArrayList<PCDifferenceItem>());
            }
            PCDifferenceItem differenceItem = new PCDifferenceItem();
            differenceItem.setDesc("服务费差价");
            differenceItem.setType("service");
            differenceItem.setAmount(actual.getServiceItems().getAmount() - prepaid.getSpecAmount());
            amount += differenceItem.getAmount();
            difference.getItems().add(differenceItem);

            differenceItem = new PCDifferenceItem();
            differenceItem.setDesc("耗材费差价");
            differenceItem.setType("package");
            differenceItem.setAmount(actual.getPackageItems().getAmount() - prepaid.getPkgAmount());
            amount += differenceItem.getAmount();
            difference.getItems().add(differenceItem);

            differenceItem = new PCDifferenceItem();
            differenceItem.setDesc("行程费差价");
            differenceItem.setType("taxi");
            differenceItem.setAmount(actual.getTaxiItems().getAmount() - prepaid.getTaxiAmount());
            amount += differenceItem.getAmount();
            difference.getItems().add(differenceItem);

            differenceItem = new PCDifferenceItem();
            differenceItem.setDesc("其他费用差价");
            differenceItem.setType("other");
            differenceItem.setAmount(actual.getOtherItems().getAmount());
            amount += differenceItem.getAmount();
            difference.getItems().add(differenceItem);

            difference.setAmount(amount);

            return difference;

        }catch (Exception e){
            return null;
        }
    }


    @Transactional
    public PCCheckInfo getCheckInfo(Long orderId) {
        try {
            List<ServicePicture> pictures = pictureMapper.selectCheckListByOrderId(orderId);
            PCCheckInfo checkInfo = new PCCheckInfo();
            checkInfo.setCheckImages(new ArrayList<String>());
            for (ServicePicture picture : pictures){
                checkInfo.getCheckImages().add(picture.getPicturePic());
                checkInfo.setCheckTips(checkInfo.getCheckTips() + " ; " + picture.getPictureRemark());
            }

            return checkInfo;

        }catch (Exception e){
            return null;
        }
    }

    @Transactional
    public PCPaidInfo getPaidInfo(Long orderId) {
        try {

            PCPaidInfo paidInfo = new PCPaidInfo();

            PCPrepaid prePaid = getPrePaid(orderId);
            PCActual actual = getActual(orderId);
            PCDifference difference = getDifference(actual, prePaid);
            paidInfo.setActual(actual);
            paidInfo.setPrePaid(prePaid);
            paidInfo.setDifference(difference);

            paidInfo.setTotalAmount(prePaid.getTotalAmount());
            if (actual != null) paidInfo.setTotalAmount(actual.getTotalAmount());

            return paidInfo;

        }catch (Exception e){
            return null;
        }
    }

    @Transactional
    public Integer orderStop(Long orderId, Long reasonId, String remark){
        ServiceOrders orders = ordersMapper.selectServiceOrdersByOrderId(orderId);
        if (orders != null){
            if (orders.getOrderServiceflag() == 14){
                orders.setOrderStatus(4);
                orders.setOrderReasonstopid(String.valueOf(reasonId));
                orders.setOrderReasonremark(remark);
                orders.setOrderUpdateBy(getUsername());
                orders.setOrderUpdateTime(new Date());
                ordersMapper.updateServiceOrders(orders);

                return 0;
            }
        }
        return 1;
    }

    @Transactional
    public List<Map<String, Object>> getStopReason(){
        try {
            List<Map<String, Object>> result = new ArrayList<>();
            ServiceReasonstop reasonStopSearch = new ServiceReasonstop();
            reasonStopSearch.setReasonDelFlag("0");
            List<ServiceReasonstop> reasonstopList = reasonstopMapper.selectServiceReasonstopList(reasonStopSearch);

            for(ServiceReasonstop reasonstop : reasonstopList){
                Map<String, Object> reasonstopMap = new HashMap<>();
                reasonstopMap.put("id", reasonstop.getReasonId());
                reasonstopMap.put("reason", reasonstop.getReasonName());
                result.add(reasonstopMap);
            }
            return result;

        }catch (Exception e){
            return null;
        }
    }

    @Transactional
    public List<PCOrderProcess> getOrderProcess(Long orderId){
        try {
            List<PCOrderProcess> timeReturnList = new ArrayList<PCOrderProcess>();
            List<ServiceTime> timeList = timeMapper.selectServiceTimeByOrderId(orderId);
            for (ServiceTime time : timeList) {
                PCOrderProcess orderTimeReturn = new PCOrderProcess();
                ServiceAction action = actionMapper.selectServiceActionByActionId(time.getTimeActionid());

                orderTimeReturn.setStatus(time.getTimeAction());
                DateFormat cstFormate = new SimpleDateFormat("yyyy/MM/dd HH:mm");
                String timeInfo = cstFormate.format(time.getTimeTime());
                orderTimeReturn.setTime(timeInfo);
                orderTimeReturn.setDesc(action.getActionName());
                orderTimeReturn.setCurrent(false);
                timeReturnList.add(orderTimeReturn);
            }
            timeReturnList.get(timeReturnList.size()-1).setCurrent(true);
            return timeReturnList;
        }catch (Exception e){
            return null;
        }
    }

    @Transactional
    public List<PCProcessItems> getOrderItems(Long orderId){
        try {
            List<PCProcessItems> items = new ArrayList<PCProcessItems>();
            List<ServiceOrderscombo> orderscomboList = orderscomboMapper.selectServiceOrderscomboByOrderId(orderId);
            ServiceOrders orders = ordersMapper.selectServiceOrdersByOrderId(orderId);
            for (ServiceOrderscombo orderscombo : orderscomboList) {
                PCProcessItems retVONode = new PCProcessItems();
                ServiceItemscombo itemscombo = itemscomboMapper.selectByComboId(orderscombo.getOrderscomboComboid());
                ServiceItems item = itemsMapper.selectServiceItemsByItemId(itemscombo.getItemscomboItemid());
                ServiceCombo combo = comboMapper.selectServiceComboByComboIdNew(orderscombo.getOrderscomboComboid());

                retVONode.setComboId(combo.getComboId());
                retVONode.setCombo(combo.getComboName());
                retVONode.setCount(orderscombo.getOrderscomboCount());

                retVONode.setItemName(item.getItemName());
                retVONode.setImg(item.getItemPicture());

                if (!orders.getOrderCreateBy().equals(orderscombo.getOrderscomboCreateBy())){
                    retVONode.setFromNur(true);
                }else {
                    retVONode.setFromNur(false);
                }
                items.add(retVONode);
            }
            return items;

        }catch (Exception e){
            return null;
        }
    }

    @Transactional
    public PCOrderProcessRet getOrderTrack(Long orderId)
    {
        PCOrderProcessRet retOrderVONode = new PCOrderProcessRet();
        try {
            ServiceOrders searchOrder = new ServiceOrders();
            searchOrder.setOrderId(orderId);

            ServiceOrders order = ordersMapper.selectServiceOrdersByOrderId(orderId);
            if (order == null){
                throw new Exception("未找到订单信息");
            }

            //订单信息
            retOrderVONode.init(order);

            //验证码
            ServiceCode code = codeMapper.selectServiceCodeByOrderId(order.getOrderId());
            ServicePay pay = payMapper.selectServicePayByPayId(order.getOrderPay());
            if (code != null){
                retOrderVONode.setOrderPayId(pay.getPayAdvancepaycode());
                DateFormat cstFormate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String payTime = cstFormate.format(pay.getPayCreateTime());
                retOrderVONode.setOrderPayTime(payTime);
            }

            ServiceUsers userInfo = usersMapper.selectServiceUsersByUsersId(order.getOrderUserid());
            retOrderVONode.initUserInfo(userInfo);

            //护士信息
            List<ServiceOrdernurse> ordernurseList = ordernurseMapper.selectServiceOrdernurseListByOrderId(order.getOrderId());
            List<PCNurseInfo> nurseInfoList = new ArrayList<PCNurseInfo>();
            for (ServiceOrdernurse ordernurse : ordernurseList) {
                ServiceNurse nurse = nurseMapper.selectServiceNurseByNurseId(ordernurse.getOrdernurseNurseid());
                if (nurse != null) {
                    PCNurseInfo nurseInfo = new PCNurseInfo();

                    nurseInfo.setId(nurse.getNurseId());
                    nurseInfo.setName(nurse.getNurseName());
                    nurseInfo.setTel(nurse.getNurseTelephonenumber());

                    nurseInfoList.add(nurseInfo);
                }
            }
            retOrderVONode.setNurseInfo(nurseInfoList);

            //被服务信息
            retOrderVONode.setServeInfo(getServeInfo(order.getOrderId()));


            List<ServiceOrderscombo> orderscomboList = orderscomboMapper.selectServiceOrderscomboByOrderId(order.getOrderId());
            for (ServiceOrderscombo orderscombo : orderscomboList) {
                PCOrderInfo retVONode = new PCOrderInfo();
                //PCOrderDetailInfo retVONode = new PCOrderDetailInfo();

                ServiceOrders orders = ordersMapper.selectServiceOrdersByOrderId(orderId);
                List<ServiceOrderspackages> orderspackagesList = orderspackagesMapper.selectOrderspackagesByOrderId(order.getOrderId());



            }

            //retOrderVONode.initOrderInfo(getPaidInfo(order.getOrderId()));
            retOrderVONode.initOrderItem(getOrderItems(order.getOrderId()));
            retOrderVONode.initProcess(getOrderProcess(order.getOrderId()));

            return retOrderVONode;

        }catch (Exception e){
            return null;
        }
    }

    @Transactional
    public Page<PCOrderPayRet> getOrderPay( Integer page, Integer size) //String labelStatus,
    {
        List<PCOrderPayRet> retPCOrderPay = new ArrayList<PCOrderPayRet>();
        PCOrderPayRet retOrderVONode = new PCOrderPayRet();
        try {

            ServiceOrders searchOrder = new ServiceOrders();

            Long[] orderServiceFlags = null;

            //if (labelStatus.equals("unNormal")){
            //    searchOrder.setOrderStatus(9);
            //}
            //
            //if (labelStatus.equals("new")){
            //    orderServiceFlags = new Long[]{5L,6L,7L};
            //} else if (labelStatus.equals("unserved")) {
            //    orderServiceFlags = new Long[]{8L};
            //} else if (labelStatus.equals("serving")) {
            //    orderServiceFlags = new Long[]{9L,10L,11L};
            //} else if (labelStatus.equals("unsettled")) {
            //    orderServiceFlags = new Long[]{12L,13L};
            //}else if (labelStatus.equals("canceled")){
            //    orderServiceFlags = new Long[]{2L,4L};
            //}else {
                orderServiceFlags = new Long[]{1L,2L,3L,4L,5L,6L,7L,8L,9L,10L,11L,12L,13L,14L,15L,16L,17L};
            //}

            List<ServiceOrders> ordersList = new ArrayList<ServiceOrders>();
            for (Long flag : orderServiceFlags) {
                searchOrder.setOrderServiceflag(Math.toIntExact(flag));

                List<ServiceOrders> ordersAll = ordersMapper.selectServiceOrdersList(searchOrder);
                for (ServiceOrders order : ordersAll){
                    ordersList.add(order);
                }
            }

            for (ServiceOrders order : ordersList) {

                //订单信息
                retOrderVONode.init(order);

                //验证码
                ServiceCode code = codeMapper.selectServiceCodeByOrderId(order.getOrderId());
                ServicePay pay = payMapper.selectServicePayByPayId(order.getOrderPay());
                if (code != null) {
                    retOrderVONode.setOrderPayId(pay.getPayAdvancepaycode());
                    DateFormat cstFormate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    String payTime = cstFormate.format(pay.getPayCreateTime());
                    retOrderVONode.setOrderPayTime(payTime);
                    if (pay.getPayFinalpay() != null){
                        String settleTime = cstFormate.format(pay.getPayUpdateTime());
                        retOrderVONode.setOrderSettleTime(settleTime);
                    }
                }

                ServiceUsers userInfo = usersMapper.selectServiceUsersByUsersId(order.getOrderUserid());
                retOrderVONode.initUserInfo(userInfo);

                //护士信息
                List<ServiceOrdernurse> ordernurseList = ordernurseMapper.selectServiceOrdernurseListByOrderId(order.getOrderId());
                List<PCNurseInfo> nurseInfoList = new ArrayList<PCNurseInfo>();
                for (ServiceOrdernurse ordernurse : ordernurseList) {
                    ServiceNurse nurse = nurseMapper.selectServiceNurseByNurseId(ordernurse.getOrdernurseNurseid());
                    if (nurse != null) {
                        PCNurseInfo nurseInfo = new PCNurseInfo();

                        nurseInfo.setId(nurse.getNurseId());
                        nurseInfo.setName(nurse.getNurseName());
                        nurseInfo.setTel(nurse.getNurseTelephonenumber());

                        nurseInfoList.add(nurseInfo);
                    }
                }
                retOrderVONode.setNurseInfo(nurseInfoList);

                int buttonFlag = 0;
                int addBTFlag = 0;
                ServiceOrders orders = ordersMapper.selectServiceOrdersByOrderId(order.getOrderId());
                List<ServiceOrderspackages> orderspackagesList = orderspackagesMapper.selectOrderspackagesByOrderId(order.getOrderId());

                if (retOrderVONode.getButtons() == null) {
                    retOrderVONode.setButtons(new ArrayList<PCOrderButton>());
                }

                for (PCOrderButton button : retOrderVONode.getButtons()) {
                    if (button.getType().equals("orderDetial")) {
                        addBTFlag = 1;
                        break;
                    }
                }
                if (addBTFlag == 0) {
                    retOrderVONode.getButtons().add(new PCOrderButton("orderDetial", "订单详情"));
                    addBTFlag = 0;
                }
                for (PCOrderButton button : retOrderVONode.getButtons()) {
                    if (button.getType().equals("orderProcess")) {
                        addBTFlag = 1;
                        break;
                    }
                }
                if (addBTFlag == 0) {
                    retOrderVONode.getButtons().add(new PCOrderButton("orderProcess", "订单跟踪"));
                    addBTFlag = 0;
                }

                //被服务信息
                retOrderVONode.setServeInfo(getServeInfo(order.getOrderId()));


                retOrderVONode.initOrderInfo(getPaidInfo(order.getOrderId()));

                retPCOrderPay.add(retOrderVONode);
            }

            // 分页逻辑
            Pageable pageable = PageRequest.of(page, size);
            int start = (int) pageable.getOffset();
            int end = Math.min((start + pageable.getPageSize()), retPCOrderPay.size());
            List<PCOrderPayRet> pagedItemsList = retPCOrderPay.subList(start, end);

            return new PageImpl<>(pagedItemsList, pageable, retPCOrderPay.size());
        }catch (Exception e){
            return null;
        }
    }

    @Transactional
    public List<PCOrderStatusRsp> getAllStatus() {
        try {
            List<PCOrderStatusRsp> retOrderStatusList = new ArrayList<PCOrderStatusRsp>();
            PCOrderStatusRsp orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("1");
            orderStatusRsp.setType("unPay");
            orderStatusRsp.setTitle("待付款");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("5");
            orderStatusRsp.setType("unSend");
            orderStatusRsp.setTitle("待派单");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("6");
            orderStatusRsp.setType("unAccept");
            orderStatusRsp.setTitle("待接单");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("8");
            orderStatusRsp.setType("unStart");
            orderStatusRsp.setTitle("待出发");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("9");
            orderStatusRsp.setType("unArrive");
            orderStatusRsp.setTitle("待抵达");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("9");
            orderStatusRsp.setType("unArrive");
            orderStatusRsp.setTitle("待抵达");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("10");
            orderStatusRsp.setType("serving");
            orderStatusRsp.setTitle("服务中");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("11");
            orderStatusRsp.setType("unSettled");
            orderStatusRsp.setTitle("待提交结算");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("12");
            orderStatusRsp.setType("unPayLast");
            orderStatusRsp.setTitle("待支付尾款");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("15");
            orderStatusRsp.setType("finisah");
            orderStatusRsp.setTitle("交易完成");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("999");
            orderStatusRsp.setType("stop");
            orderStatusRsp.setTitle("交易关闭");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("2");
            orderStatusRsp.setType("canceled");
            orderStatusRsp.setTitle("已取消");
            retOrderStatusList.add(orderStatusRsp);

            return retOrderStatusList;
        } catch (Exception e) {
            return null;
        }
    }

    @Transactional
    public List<PCOrderStatusRsp> getPayStatus() {
        try {
            List<PCOrderStatusRsp> retOrderStatusList = new ArrayList<PCOrderStatusRsp>();
            PCOrderStatusRsp orderStatusRsp = new PCOrderStatusRsp();

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("11");
            orderStatusRsp.setType("unSettled");
            orderStatusRsp.setTitle("待提交结算");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("12");
            orderStatusRsp.setType("settled");
            orderStatusRsp.setTitle("已提交结算");
            retOrderStatusList.add(orderStatusRsp);

            return retOrderStatusList;
        } catch (Exception e) {
            return null;
        }
    }

    @Transactional
    public List<PCOrderStatusRsp> getErrorStatus() {
        try {
            List<PCOrderStatusRsp> retOrderStatusList = new ArrayList<PCOrderStatusRsp>();
            PCOrderStatusRsp orderStatusRsp = new PCOrderStatusRsp();

            orderStatusRsp.setId("0");
            orderStatusRsp.setType("all");
            orderStatusRsp.setTitle("全部");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("E1");
            orderStatusRsp.setType("otSend");
            orderStatusRsp.setTitle("超时预警(派单)");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("E2");
            orderStatusRsp.setType("otAccept");
            orderStatusRsp.setTitle("超时预警(接单)");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("E3");
            orderStatusRsp.setType("otStart");
            orderStatusRsp.setTitle("超时未开始");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("E4");
            orderStatusRsp.setType("otEnd");
            orderStatusRsp.setTitle("超时未结束服务");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("E5");
            orderStatusRsp.setType("otCheck");
            orderStatusRsp.setTitle("超时未提交结算");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("E6");
            orderStatusRsp.setType("otEndPay");
            orderStatusRsp.setTitle("超时未结算尾款");
            retOrderStatusList.add(orderStatusRsp);

            orderStatusRsp = new PCOrderStatusRsp();
            orderStatusRsp.setId("E99");
            orderStatusRsp.setType("refusePay");
            orderStatusRsp.setTitle("拒绝支付尾款");
            retOrderStatusList.add(orderStatusRsp);

            return retOrderStatusList;
        } catch (Exception e) {
            return null;
        }
    }

    @Transactional
    public List<PCItemPayVO> getItemPay() {
        try {
            List<PCItemPayVO> retItemList = new ArrayList<PCItemPayVO>();
            PCItemPayVO itemRsp = new PCItemPayVO();

            List<ServiceItems> items = itemsMapper.selectServiceItemsListNew();
            for (ServiceItems itemNode : items){
                itemRsp = new PCItemPayVO(itemNode);
                retItemList.add(itemRsp);
            }

            return retItemList;
        } catch (Exception e) {
            return null;
        }
    }

}
